﻿using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Threading.BackgroundWorkers;
using Abp.Threading.Timers;
using ARchGL.Platform.Core;
using ARchGL.Platform.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ARchGL.Platform.BackgroundWorker
{
    /// <summary>
    /// 巡检/自检 报表数据提取
    /// </summary>
    public class ReportWarehousesWorker : PeriodicBackgroundWorkerBase, ISingletonDependency
    {
        private readonly IRepository<SelfChecks, Guid> selfChecksRepository;
        private readonly IRepository<SecurityChecks, Guid> securityChecksRepository;
        private readonly IRepository<ReportWarehouses, Guid> reportWarehousesRepository;
        private const string format = "yyyy-MM";

        public ReportWarehousesWorker(AbpTimer timer, IRepository<SelfChecks, Guid> _selfChecksRepository, IRepository<SecurityChecks, Guid> _securityChecksRepository,
            IRepository<ReportWarehouses, Guid> _reportWarehousesRepository)
            : base(timer)
        {
            selfChecksRepository = _selfChecksRepository;
            securityChecksRepository = _securityChecksRepository;
            reportWarehousesRepository = _reportWarehousesRepository;
            //Timer.Period = 5000; //5秒一次
            //Timer.Period = 3600000; //1小时一次轮询
            Timer.Period = 3000000; //50分钟一次轮询
        }

        [UnitOfWork]
        protected override void DoWork()
        {
            if (DateTime.Now.Hour == 2) Init(); //凌晨2点执行一次

            //if (DateTime.Now.Second == 2)
            //    Init();
        }

        protected void Init()
        {
            var securityDict = new Dictionary<string, int[]>();
            var selfDict = new Dictionary<string, int[]>();
            var currentDateTime = DateTime.Now.ToString(format);

            #region 巡检
            {
                //1.查询出数据库中一共包含多少个月的数据
                var securityChecksGroupList = from sc in securityChecksRepository.GetAll()
                                              group sc by sc.CreationTime.ToString(format) into sc
                                              select sc.Key;

                //2.查询仓库中有几个月的数据
                var reportWarehousesGroupList = from rw in reportWarehousesRepository.GetAll()
                                                where rw.Type == 1
                                                group rw by rw.DateTime into rw
                                                select rw.Key;

                if (securityChecksGroupList.Count() == reportWarehousesGroupList.Count()) return;

                //3.补充缺少的数据
                var dateList = securityChecksGroupList.Where(x => !reportWarehousesGroupList.Contains(x));

                var securityCheckList = from sc in securityChecksRepository.GetAll()
                                        where dateList.Contains(sc.CreationTime.ToString(format))
                                        select new { sc.Status, sc.CreationTime };
                foreach (var item in securityCheckList)
                {
                    var date = item.CreationTime.ToString(format);
                    if (date == currentDateTime) continue; //跳过本月数据
                    var index = item.Status != EnumCheckAndFeedbackStatus.已完成 ? 0 : 1;
                    if (securityDict.ContainsKey(date))
                        securityDict[date][index] += 1;
                    else
                        securityDict.Add(date, new int[2]);
                }
            }
            #endregion

            #region 自检
            {
                //1.查询出数据库中一共包含多少个月的数据
                var selfChecksGroupList = from sc in selfChecksRepository.GetAll()
                                          group sc by sc.CreationTime.ToString(format) into sc
                                          select sc.Key;

                //2.查询仓库中有几个月的数据
                var reportWarehousesGroupList = from rw in reportWarehousesRepository.GetAll()
                                                where rw.Type == 2
                                                group rw by rw.DateTime into rw
                                                select rw.Key;

                if (selfChecksGroupList.Count() == reportWarehousesGroupList.Count()) return;

                //3.补充缺少的数据
                var dateList = selfChecksGroupList.Where(x => !reportWarehousesGroupList.Contains(x));

                var selfCheckList = from sc in securityChecksRepository.GetAll()
                                    where dateList.Contains(sc.CreationTime.ToString(format))
                                    select new { sc.Status, sc.CreationTime };

                var selfList = from sc in selfChecksRepository.GetAll() select new { sc.Status, sc.CreationTime };
                foreach (var item in selfList)
                {
                    var date = item.CreationTime.ToString(format);
                    if (date == currentDateTime) continue; //跳过本月数据
                    var index = item.Status != EnumSelfCheckStatus.已整改 ? 0 : 1;
                    if (selfDict.ContainsKey(date))
                        selfDict[date][index] += 1;
                    else
                        selfDict.Add(date, new int[2]);
                }
            }
            #endregion

            InsertAsync(securityDict, 1);
            InsertAsync(selfDict, 2);
        }

        private void InsertAsync(Dictionary<string, int[]> dict, int type)
        {
            foreach (var item in dict)
            {
                var entity = new ReportWarehouses
                {
                    Type = type,
                    DateTime = item.Key,
                    Year = int.Parse(item.Key.Substring(0, 4)),
                    Values = item.Value.ToArray().SerializeObject(),
                    TenantId = 1
                };
                reportWarehousesRepository.InsertAsync(entity);
            }
        }
    }
}
